local M={
    tiles={},
    showedTileCount=0,
    colors={
        ["2"]={r=204,g=41,b=41,a=255},
        ["4"]={r=204,g=139,b=41,a=255},
        ["8"]={r=171,g=204,b=41,a=255},
        ["16"]={r=73,g=204,b=41,a=255},
        ["32"]={r=41,g=204,b=106,a=255},
        ["64"]={r=41,g=204,b=204,a=255},
        ["128"]={r=204,g=139,b=41,a=255},
        ["258"]={r=204,g=139,b=41,a=255},
        ["512"]={r=204,g=139,b=41,a=255},
        ["1024"]={r=204,g=139,b=4,a=255}
    }
}

function M:RandomNewTile()
    if self.showedTileCount == 16 then
        return false
    end
    local index=math.random(1,16-self.showedTileCount)
    local counter=0
    for i=1,16,1 do
        if self.tiles[i].Visiable then
        else
            counter=counter+1
            if counter==index then
                --find the tile
                self.tiles[i].Visiable=true
                self.tiles[i].Text:Show()
                self.tiles[i].Tile:Call("ShowUp")
                self.tiles[i].BKG:SetColor(204,41,41,255)
                self.tiles[i].Number=2
                self.showedTileCount=self.showedTileCount+1
                return true
            end
        end
    end
    return false
end

function M:Awake()
    local content=Alice.GameObject.Find("Content")
    Alice.Console.Debug(content:GetName())
    for i=1,16,1 do
        local tile=content:FindChild(tostring(i))
        self.tiles[i]={}
        self.tiles[i].Tile=tile
        self.tiles[i].BKG=tile:GetComponent(Alice.ImageSprite)
        local text=tile:FindChild("Text")
        self.tiles[i].Text=text
        local label=text:GetComponent(Alice.Label)
        self.tiles[i].Label=label
        self.tiles[i].Number=2
        self.tiles[i].Visiable=false
        text:Hide()
    end
    math.randomseed(os.time())
    self:RandomNewTile()
    self:RandomNewTile()
    local is=self.GameObject:GetComponent(Alice.ImageSprite)
    is:EnableClickEvent(true)
end

function M:Dump()
    Alice.Console.Debug(self.tiles[13].Visiable,self.tiles[14].Visiable,self.tiles[15].Visiable,self.tiles[16].Visiable)
    Alice.Console.Debug(self.tiles[9].Visiable,self.tiles[10].Visiable,self.tiles[11].Visiable,self.tiles[12].Visiable)
    Alice.Console.Debug(self.tiles[5].Visiable,self.tiles[6].Visiable,self.tiles[7].Visiable,self.tiles[8].Visiable)
    Alice.Console.Debug(self.tiles[1].Visiable,self.tiles[2].Visiable,self.tiles[3].Visiable,self.tiles[4].Visiable)
end

function M:OnTouchBegin(x,y,id)
    self.TouchX=x
    self.TouchY=y
    self.TouchID=id
end

function M:MoveLeft()
    local prevIndex=1
    for i=1,16,1 do
        if i==1 or i==5 or i==9 or i==13 then
            prevIndex=i
        else
            if self.tiles[prevIndex].Visiable then
                if self.tiles[i].Visiable then
                    local distance=i-prevIndex
                    if self.tiles[i].Number==self.tiles[prevIndex].Number then
                        --combine
                        self.tiles[prevIndex].Number=self.tiles[prevIndex].Number*2
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[i].Text:Hide()
                        self.tiles[i].Visiable=false
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.showedTileCount=self.showedTileCount-1
                    else
                        --
                        if distance>1 then
                            --move i -> prevIndex+1
                            prevIndex=prevIndex+1
                            self.tiles[prevIndex].Number=self.tiles[i].Number
                            self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                            self.tiles[prevIndex].Text:Show()
                            self.tiles[prevIndex].Tile:Call("ShowUp")
                            self.tiles[prevIndex].Visiable=true
                            local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                            self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                            self.tiles[i].Text:Hide()
                            self.tiles[i].Visiable=false
                            self.tiles[i].BKG:SetColor(255,255,255,255)
                        else
                            --do nothing
                            prevIndex=i
                        end
                    end
                else
                --do nothing
                end
            else
                ---prev is not Visiable
                if self.tiles[i].Visiable then
                --move i -> prevIndex
                    self.tiles[prevIndex].Number=self.tiles[i].Number
                    self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                    self.tiles[prevIndex].Text:Show()
                    self.tiles[prevIndex].Tile:Call("ShowUp")
                    self.tiles[prevIndex].Visiable=true
                    local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                    self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                    self.tiles[i].Text:Hide()
                    self.tiles[i].Visiable=false
                    self.tiles[i].BKG:SetColor(255,255,255,255)
                else
                --do ,nothing
                end
            end
        end
    end
end

function M:MoveRight()
    local prevIndex=1
    for i=16,1,-1 do
        if i==4 or i==8 or i==12 or i==16 then
            prevIndex=i
        else
            if self.tiles[prevIndex].Visiable then
                if self.tiles[i].Visiable then
                    local distance=prevIndex-i
                    if self.tiles[i].Number==self.tiles[prevIndex].Number then
                        --combine
                        self.tiles[prevIndex].Number=self.tiles[prevIndex].Number*2
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[i].Text:Hide()
                        self.tiles[i].Visiable=false
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.showedTileCount=self.showedTileCount-1
                    else
                        --
                        if distance>1 then
                        --move i -> prevIndex+1
                        prevIndex=prevIndex-1
                        self.tiles[prevIndex].Number=self.tiles[i].Number
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        self.tiles[prevIndex].Text:Show()
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[prevIndex].Visiable=true
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[i].Text:Hide()
                        
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.tiles[i].Visiable=false
                        else
                            --do nothing
                            prevIndex=i
                        end
                    end
                else
                --do nothing
                end
            else
                ---prev is not Visiable
                if self.tiles[i].Visiable then
                --move i -> prevIndex
                    self.tiles[prevIndex].Number=self.tiles[i].Number
                    self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                    self.tiles[prevIndex].Text:Show()
                    self.tiles[prevIndex].Tile:Call("ShowUp")
                    self.tiles[prevIndex].Visiable=true
                    local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                    self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                    self.tiles[i].Text:Hide()
                    self.tiles[i].BKG:SetColor(255,255,255,255)
                    self.tiles[i].Visiable=false
                else
                --do nothing
                end
            end
        end
    end
end

function M:MoveUp()
    local prevIndex=1
    for k=13,16,1 do
        prevIndex=k
        for j=1,3,1 do
            local i=k-j*4
            if self.tiles[prevIndex].Visiable then
                if self.tiles[i].Visiable then
                    local distance=(prevIndex-i)/4
                    if self.tiles[i].Number==self.tiles[prevIndex].Number then
                        --combine
                        self.tiles[prevIndex].Number=self.tiles[prevIndex].Number*2
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[i].Text:Hide()
                        self.tiles[i].Visiable=false
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.showedTileCount=self.showedTileCount-1
                    else
                        --
                        if distance>1 then
                        --move i -> prevIndex+1
                        prevIndex=prevIndex-4
                        self.tiles[prevIndex].Number=self.tiles[i].Number
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        self.tiles[prevIndex].Text:Show()
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[prevIndex].Visiable=true
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[i].Text:Hide()
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.tiles[i].Visiable=false
                        else
                            --do nothing
                            prevIndex=i
                        end
                    end
                else
                --do nothing
                end
            else
                ---prev is not Visiable
                if self.tiles[i].Visiable then
                --move i -> prevIndex
                    self.tiles[prevIndex].Number=self.tiles[i].Number
                    self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                    self.tiles[prevIndex].Text:Show()
                    self.tiles[prevIndex].Tile:Call("ShowUp")
                    self.tiles[prevIndex].Visiable=true
                    local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                    self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                    self.tiles[i].Text:Hide()
                    self.tiles[i].BKG:SetColor(255,255,255,255)
                    self.tiles[i].Visiable=false
                else
                --do nothing
                end
            end
        end
    end
end

function M:MoveDown()
    local prevIndex=1
    for k=1,4,1 do
        prevIndex=k
        for j=1,3,1 do
            local i=k+j*4
            if self.tiles[prevIndex].Visiable then
                if self.tiles[i].Visiable then
                    local distance=(i-prevIndex)/4
                    if self.tiles[i].Number==self.tiles[prevIndex].Number then
                        --combine
                        self.tiles[prevIndex].Number=self.tiles[prevIndex].Number*2
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[i].Text:Hide()
                        self.tiles[i].Visiable=false
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.showedTileCount=self.showedTileCount-1
                    else
                        --
                        if distance>1 then
                        --move i -> prevIndex+1
                        prevIndex=prevIndex+4
                        self.tiles[prevIndex].Number=self.tiles[i].Number
                        self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                        self.tiles[prevIndex].Text:Show()
                        self.tiles[prevIndex].Tile:Call("ShowUp")
                        self.tiles[prevIndex].Visiable=true
                        local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                        self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                        self.tiles[i].Text:Hide()
                        self.tiles[i].BKG:SetColor(255,255,255,255)
                        self.tiles[i].Visiable=false
                        else
                            --do nothing
                            prevIndex=i
                        end
                    end
                else
                --do nothing
                end
            else
                ---prev is not Visiable
                if self.tiles[i].Visiable then
                --move i -> prevIndex
                    self.tiles[prevIndex].Number=self.tiles[i].Number
                    self.tiles[prevIndex].Label:SetText(tostring(self.tiles[prevIndex].Number))
                    self.tiles[prevIndex].Text:Show()
                    self.tiles[prevIndex].Tile:Call("ShowUp")
                    self.tiles[prevIndex].Visiable=true
                    local color=self.colors[tostring(self.tiles[prevIndex].Number)]
                    self.tiles[prevIndex].BKG:SetColor(color.r,color.g,color.b,color.a)
                    self.tiles[i].Text:Hide()
                    self.tiles[i].BKG:SetColor(255,255,255,255)
                    self.tiles[i].Visiable=false
                else
                --do nothing
                end
            end
        end
    end
end

function M:OnTouchEnd(x,y)
    local deltaX=x-self.TouchX
    local deltaY=y-self.TouchY
    if math.abs(deltaX)>math.abs(deltaY) then
        if deltaX > 0 then
            self:MoveRight()
        else
            self:MoveLeft()
        end
    else
        if deltaY > 0 then
            self:MoveUp()
        else
            self:MoveDown()
        end
    end
    if not self:RandomNewTile() then
        print("game over")
    end
end

return  M